<template>
  <n-collapse-transition :show="true">
    <div class="message" :class="{ self: message.isUser }" :data-is-user="message.isUser">
      <!-- 调试信息 -->
      <div v-if="showDebug" class="debug-info">
        ID: {{ message.id }}, 
        isUser: {{ message.isUser }}, 
        CSS类: {{ message.isUser ? 'message self' : 'message' }}, 
        预期位置: {{ message.isUser ? '右侧' : '左侧' }},
        内容: {{ message.content.substring(0, 30) }}...
      </div>
      <div class="message-content">
        <n-avatar
          v-if="!message.isUser"
          :size="32"
          :src="characterAvatar"
          :fallback-src="'/src/assets/characters/default.svg'"
          class="message-avatar"
        />
        
        <div class="bubble-container">
          <div class="bubble" :class="{ streaming: message.streaming }">
            <div v-if="!message.isUser && characterName" class="character-name">
              {{ characterName }}
            </div>
            
            <!-- 语音消息显示波形 -->
            <VoiceWaveform 
              v-if="isVoiceMessage"
              :duration="voiceDuration"
              :is-playing="isPlaying"
              :is-user="message.isUser"
              @click="playVoiceMessage"
            />
            
            <!-- 普通文字消息 -->
            <div v-else class="content">
              <span v-html="safeContent"></span><span v-if="message.streaming" class="typing-cursor-inline">|</span>
            </div>
            
            <div class="message-footer">
              <n-button
                v-if="!message.isUser && (message.audioUrl || isVoiceMessage)"
                text
                size="small"
                class="audio-btn"
                @click="playVoiceMessage"
              >
                <template #icon>
                  <svg class="audio-icon" :class="{ playing: isPlaying }" viewBox="0 0 24 24">
                    <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>
                  </svg>
                </template>
              </n-button>
            </div>
          </div>
        </div>
        
        <!-- 用户头像已移除，只保留角色头像 -->
      </div>
    </div>
  </n-collapse-transition>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { NAvatar, NButton, NCollapseTransition } from 'naive-ui'
import { useChatStore, type ChatMessage } from '@/stores/chat'
import { marked } from 'marked'
import VoiceWaveform from './VoiceWaveform.vue'

interface Props {
  message: ChatMessage
}

const props = defineProps<Props>()
const chatStore = useChatStore()
const isPlaying = ref(false)

// 语音消息相关计算属性（在文件末尾重新定义）

const voiceDuration = computed(() => {
  if (props.message.voiceDuration) {
    return props.message.voiceDuration
  }
  
  // 从内容中提取时长（格式：🎵 5"）
  const match = props.message.content.match(/🎵\s*(\d+)"/)
  return match ? parseInt(match[1]) : 3
})

// 调试模式 - 可以通过 localStorage 控制
const showDebug = ref(localStorage.getItem('CHAT_DEBUG') === 'true')

// 🔍 监控 message.isUser 的变化
watch(() => props.message.isUser, (newValue, oldValue) => {
  if (oldValue !== undefined && newValue !== oldValue) {
    console.warn('🚨 [ChatMessage] 消息的 isUser 字段发生了变化！', {
      messageId: props.message.id,
      from: oldValue,
      to: newValue,
      content: props.message.content.substring(0, 30) + '...'
    })
  }
  
  console.log('[ChatMessage] 消息渲染:', {
    messageId: props.message.id,
    isUser: props.message.isUser,
    content: props.message.content.substring(0, 30) + '...',
    expectedPosition: props.message.isUser ? '右侧' : '左侧'
  })
}, { immediate: true })

const characterName = computed(() => {
  const character = chatStore.characters.find(c => c.id === props.message.characterId)
  return character?.name || ''
})

const characterAvatar = computed(() => {
  const character = chatStore.characters.find(c => c.id === props.message.characterId)
  return character?.avatar || '/src/assets/characters/default.webp'
})

// 配置 marked 选项
marked.setOptions({
  breaks: true,        // 支持换行符转换为 <br>
  gfm: true,          // 启用 GitHub Flavored Markdown
  sanitize: false,    // 不自动清理HTML（我们会手动处理）
  smartypants: true   // 启用智能标点符号
})

const safeContent = computed(() => {
  const content = props.message.content
  
  // 如果是用户消息，只进行简单的HTML转义
  if (props.message.isUser) {
    return content
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#x27;')
      .replace(/\n/g, '<br>')
  }
  
  // 如果是AI消息，使用Markdown渲染
  try {
    // 使用 marked 解析 Markdown
    const htmlContent = marked.parse(content)
    
    // 基本的XSS防护 - 移除潜在危险的标签和属性
    return htmlContent
      .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
      .replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '')
      .replace(/javascript:/gi, '')
      .replace(/on\w+\s*=/gi, '')
  } catch (error) {
    console.error('[ChatMessage] Markdown解析失败:', error)
    // 如果Markdown解析失败，回退到简单的HTML转义
    return content
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#x27;')
      .replace(/\n/g, '<br>')
  }
})


const playAudio = async () => {
  if (!props.message.audioUrl || isPlaying.value) return
  
  try {
    isPlaying.value = true
    const audio = new Audio(props.message.audioUrl)
    
    audio.onended = () => {
      isPlaying.value = false
    }
    
    audio.onerror = () => {
      isPlaying.value = false
      console.error('音频播放失败')
    }
    
    await audio.play()
  } catch (error) {
    isPlaying.value = false
    console.error('音频播放失败:', error)
  }
}

// 播放语音消息
const playVoiceMessage = async () => {
  if (isPlaying.value) return
  
  // 如果有音频URL，播放音频
  if (props.message.audioUrl) {
    await playAudio()
    return
  }
  
  // 如果没有音频URL，可能需要重新生成TTS
  console.log('[ChatMessage] 语音消息没有音频URL，需要重新生成TTS')
  // 这里可以添加重新生成TTS的逻辑
}

// 检查是否为语音消息（增强判断逻辑）
const isVoiceMessage = computed(() => {
  return props.message.isVoiceMessage || 
         props.message.content.includes('🎵') ||
         (props.message.audioUrl && !props.message.isUser)
})
</script>

<style scoped>
.message {
  margin-bottom: var(--spacing-lg);
  animation: messageIn 0.3s ease-out;
}

/* 调试信息样式 */
.debug-info {
  font-size: 10px;
  background: #1f2937;
  color: #f9fafb;
  padding: 4px 8px;
  border-radius: 4px;
  margin-bottom: 8px;
  font-family: monospace;
}

@keyframes messageIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-content {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-sm);
  max-width: 80%;
}

.message.self .message-content {
  margin-left: auto;
  flex-direction: row-reverse;
}

.message-avatar {
  border-radius: var(--radius-sm) !important;
  flex-shrink: 0;
}

.user-avatar {
  background: var(--primary-500) !important;
}

.bubble-container {
  position: relative;
  max-width: 480px;
}

.bubble {
  background: white;
  border-radius: var(--radius-lg);
  padding: var(--spacing-md) var(--spacing-lg);
  box-shadow: var(--shadow-base);
  border: 1px solid var(--gray-200);
  position: relative;
}

.message.self .bubble {
  background: linear-gradient(135deg, var(--primary-500), var(--primary-600));
  color: white;
  border: none;
}

.bubble.streaming {
  border-color: var(--primary-300);
  box-shadow: 0 0 0 2px var(--primary-100);
}

.character-name {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--primary-600);
  margin-bottom: var(--spacing-xs);
}

.content {
  font-size: var(--font-base);
  line-height: 1.6;
  color: var(--gray-800);
  word-wrap: break-word;
}

.message.self .content {
  color: white;
}

/* Markdown 样式 */
.content :deep(h1),
.content :deep(h2),
.content :deep(h3),
.content :deep(h4),
.content :deep(h5),
.content :deep(h6) {
  margin: 16px 0 8px 0;
  font-weight: 600;
  line-height: 1.4;
}

.content :deep(h1) { font-size: 1.5em; }
.content :deep(h2) { font-size: 1.3em; }
.content :deep(h3) { font-size: 1.1em; }
.content :deep(h4) { font-size: 1em; }

.content :deep(p) {
  margin: 8px 0;
  line-height: 1.6;
}

.content :deep(ul),
.content :deep(ol) {
  margin: 8px 0;
  padding-left: 20px;
}

.content :deep(li) {
  margin: 4px 0;
  line-height: 1.5;
}

.content :deep(blockquote) {
  margin: 12px 0;
  padding: 8px 16px;
  border-left: 4px solid var(--primary-300);
  background: var(--gray-50);
  border-radius: 0 4px 4px 0;
  font-style: italic;
}

.message.self .content :deep(blockquote) {
  border-left-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.1);
}

.content :deep(code) {
  background: var(--gray-100);
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 0.9em;
}

.message.self .content :deep(code) {
  background: rgba(255, 255, 255, 0.2);
}

.content :deep(pre) {
  margin: 12px 0;
  padding: 12px;
  background: var(--gray-900);
  color: var(--gray-100);
  border-radius: 6px;
  overflow-x: auto;
  font-family: 'Fira Code', 'Consolas', monospace;
  font-size: 0.9em;
  line-height: 1.4;
}

.content :deep(pre code) {
  background: none;
  padding: 0;
  color: inherit;
}

.content :deep(strong) {
  font-weight: 600;
}

.content :deep(em) {
  font-style: italic;
}

.content :deep(a) {
  color: var(--primary-600);
  text-decoration: underline;
}

.message.self .content :deep(a) {
  color: rgba(255, 255, 255, 0.9);
}

.content :deep(table) {
  margin: 12px 0;
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9em;
}

.content :deep(th),
.content :deep(td) {
  border: 1px solid var(--gray-300);
  padding: 8px 12px;
  text-align: left;
}

.content :deep(th) {
  background: var(--gray-100);
  font-weight: 600;
}

.message.self .content :deep(th) {
  background: rgba(255, 255, 255, 0.2);
}

.message.self .content :deep(th),
.message.self .content :deep(td) {
  border-color: rgba(255, 255, 255, 0.3);
}

.content :deep(hr) {
  margin: 16px 0;
  border: none;
  border-top: 1px solid var(--gray-300);
}

.message.self .content :deep(hr) {
  border-top-color: rgba(255, 255, 255, 0.3);
}

.message-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--spacing-sm);
  gap: var(--spacing-sm);
}


.audio-btn {
  color: var(--primary-500) !important;
  padding: 2px !important;
}

.message.self .audio-btn {
  color: rgba(255, 255, 255, 0.9) !important;
}

.audio-icon {
  width: 16px;
  height: 16px;
  fill: currentColor;
  transition: transform 0.2s ease;
}

.audio-icon.playing {
  animation: audioPlaying 1s ease-in-out infinite;
}

@keyframes audioPlaying {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

.typing-cursor-inline {
  color: var(--primary-500);
  font-weight: bold;
  animation: blink 1s infinite;
  display: inline;
  vertical-align: baseline;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* 移动端适配 */
@media (max-width: 768px) {
  .message-content {
    max-width: 90%;
  }
  
  .bubble-container {
    max-width: 320px;
  }
  
  .bubble {
    padding: var(--spacing-sm) var(--spacing-md);
  }
}
</style>
